Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / docs / decisions / koin-migration.md

Displaying Rendered • View rawDownload

docs/decisions/koin-migration.md copilot/create-implementation-plan (228d872f) Text, 2.08 KB

Decision: Hilt → Koin Migration

│ Date: 2026-02-20 to 2026-03-09 | Status: Complete

Context

Hilt (Dagger) was the strongest remaining barrier to KMP adoption — it requires Android-specific annotation processing and can't run in T383838commonMain.

Decision

Migrated to Koin 4.2.0-RC1 with the K2 Compiler Plugin (T383838io.insert-koin.compiler.plugin) and later upgraded to 0.4.1.

Key choices:
• T383838@KoinViewModel replaces T383838@HiltViewModel; T383838koinViewModel() replaces T383838hiltViewModel()
• T383838@Module + T383838@ComponentScan in T383838commonMain modules (valid 2026 KMP pattern)
• T383838@KoinWorker replaces T383838@HiltWorker for WorkManager
• T383838@InjectedParam replaces T383838@Assisted for factory patterns
• Root graph assembly centralized in T383838AppKoinModule; shared modules expose annotated definitions
Koin 0.4.1 A1 Compile Safety Disabled: Meshtastic heavily utilizes dependency inversion across KMP modules (e.g., interfaces defined in T383838core:repository are implemented in T383838core:data). Koin 0.4.x's per-module A1 validation strictly enforces that all dependencies must be explicitly provided or included locally, breaking this clean architecture. We have globally disabled A1 T383838compileSafety in T383838KoinConventionPlugin to properly rely on Koin's A3 full-graph validation at the composition root (T383838startKoin).

Gotchas Discovered

1. K2 Compiler Plugin signature collision: Multiple T383838@Single providers with identical JVM signatures in the same T383838@Module cause T383838ClassCastException. Fix: split into separate T383838@Module classes.
2. Circular dependencies: T383838Lazy<T> injection can still T383838StackOverflowError if T383838Lazy is accessed too early (e.g., in T383838init coroutine). Fix: pass dependencies as function parameters instead.
3. Robolectric T383838KoinApplicationAlreadyStartedException: Call T383838stopKoin() in T383838onTerminate.

Consequences

• Hilt completely removed
• All 23 KMP modules can contain Koin-annotated definitions
• Desktop bootstraps its own T383838DesktopKoinModule with stubs + real implementations
• 11 passthrough Android ViewModel wrappers eliminated

Served by rngit 1.5.0 - Generated in 0.03s